package soa.security.rs.oauth2;

import org.apache.commons.lang3.StringUtils;
import org.apache.cxf.common.security.SimplePrincipal;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.jaxrs.utils.JAXRSUtils;
import org.apache.cxf.message.Message;
import org.apache.cxf.security.SecurityContext;
import org.apache.cxf.transport.http.AbstractHTTPDestination;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.security.Principal;

@Provider
// TODO
public class SecurityContextFilter implements ContainerRequestFilter {

    @Context
    private HttpHeaders headers;

    private String authUrl;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        Message message = JAXRSUtils.getCurrentMessage();

        HttpServletRequest request = (HttpServletRequest) message.get(AbstractHTTPDestination.HTTP_REQUEST);

        String appKey = request.getParameter("appKey");
        String appSecret = request.getParameter("appSecret");


        String re = null;
        try {

            if (StringUtils.isBlank(appKey) || StringUtils.isBlank(appSecret)) {
                throw new IOException("appKey或者appSecret不能为空");
            }

            WebClient client = createWebClient(appKey, appSecret);
            re = client.get(String.class);

            if (!"true".equals(re)) {
                throw new IOException("app未找到或者未审核");
            }
        } catch (Exception e) {
            throw new IOException("app未找到或者未审核");
        }

//
//
//		String accountName = null;
//
//		SecurityContext sc = message.get(SecurityContext.class);
//		if (sc != null) {
//			Principal principal = sc.getUserPrincipal();
//			if (principal != null) {
//				accountName = principal.getName();
//
//				User user = userRepository.findByUsername(accountName);
//
//				if (user == null) {
//					requestContext.abortWith(createFaultResponse());
//				} else {
//					setNewSecurityContext(message, user.getUsername());
//				}
//				return;
//			}
//		}
//
//		List<String> authValues = headers.getRequestHeader("Authorization");
//		if (authValues == null || authValues.size() != 1) {
//			requestContext.abortWith(createFaultResponse());
//			return;
//		}
//		String[] values = authValues.get(0).split(" ");
//		if (values.length != 2 || !"Basic".equals(values[0])) {
//			requestContext.abortWith(createFaultResponse());
//			return;
//		}
//
//		String decodedValue = null;
//		try {
//			decodedValue = new String(Base64Utility.decode(values[1]));
//		} catch (Base64Exception ex) {
//			requestContext.abortWith(createFaultResponse());
//			return;
//		}
//
//		String[] namePassword = decodedValue.split(":");
//		if (namePassword.length != 2) {
//			requestContext.abortWith(createFaultResponse());
//			return;
//		}
//
//		final User user = userRepository.findByUsernameAndPassword(namePassword[0], namePassword[1]);
//		if (user == null) {
//			requestContext.abortWith(createFaultResponse());
//			return;
//		}
//
//		setNewSecurityContext(message, user.getUsername());
    }

    private void setNewSecurityContext(Message message, final String user) {
        final SecurityContext newSc = new SecurityContext() {

            public Principal getUserPrincipal() {
                return new SimplePrincipal(user);
            }

            public boolean isUserInRole(String arg0) {
                return false;
            }

        };
        message.put(SecurityContext.class, newSc);
    }

    private Response createFaultResponse() {
        return Response.status(401).header("WWW-Authenticate", "Basic realm=\"Social.com\"").build();
    }

    WebClient createWebClient(String appKey, String appSecret) {
        return WebClient.create(getAuthUrl() + "?appKey=" + appKey + "&appSecret=" + appSecret);
    }


    public String getAuthUrl() {
        return authUrl;
    }

    public void setAuthUrl(String authUrl) {
        this.authUrl = authUrl;
    }
}
